#!/bin/bash
WAFER_DIR := ../../..
WAFER_OPT := ${WAFER_DIR}/build/bin/wafer-opt
WAFER_TRANSLATE := ${WAFER_DIR}/build/bin/wafer-translate
WAFER_FRONTEND := ${WAFER_DIR}/build/bin/wafer-frontend
MLIR_CPU_RUNNER := ${WAFER_DIR}/3rdparty/llvm/build/bin/mlir-cpu-runner
LLC := ${WAFER_DIR}/3rdparty/llvm/build/bin/llc
CLANG := ${WAFER_DIR}/3rdparty/llvm/build/bin/clang++
LLVM-LINK := ${WAFER_DIR}/3rdparty/llvm/build/bin/llvm-link
PTXAS := /usr/local/cuda/bin/ptxas
FATBINARY := /usr/local/cuda/bin/fatbinary
INCLUDE := /usr/lib/gcc/x86_64-linux-gnu/11/include
OPT_FLAG := -O0

ifeq ($(shell uname),Linux)
MLIR_RUNNER_UTILS := ${WAFER_DIR}/3rdparty/llvm/build/lib/libmlir_runner_utils.so
MLIR_C_RUNNER_UTILS := ${WAFER_DIR}/3rdparty/llvm/build/lib/libmlir_c_runner_utils.so
MTRIPLE := x86_64-unknown-linux-gnu
else ifeq ($(shell uname),Darwin)
MLIR_RUNNER_UTILS := ${WAFER_DIR}/3rdparty/llvm/build/lib/libmlir_runner_utils.dylib
MLIR_C_RUNNER_UTILS := ${WAFER_DIR}/3rdparty/llvm/build/lib/libmlir_c_runner_utils.dylib
MTRIPLE := x86_64-apple-darwin
endif

default:
	${WAFER_FRONTEND} foo.cpp -I ${INCLUDE} \
	    --JsonFilePath ../../../design.json --wafer-to-llvmir -o share.ll
	@has_gpu_code=$$(grep -q "call void @mgpuLaunchKernel" share.ll && echo 1 || echo 0); \
	if [ "$$has_gpu_code" -eq "0" ]; then \
	    echo "cpu.out generated successfully."; \
	    target=cpu; \
	else \
	    echo "gpu.out generated successfully."; \
	    target=gpu; \
	fi; \
	$(MAKE) $$target

cpu: share.ll
	@${CLANG} foo.cpp share.ll -o cpu.out

foo.o: foo.cpp
	@${CLANG} -c foo.cpp -I ${INCLUDE} -o foo.o

gpu: gpu.o foo.o
	@${CLANG} gpu.o foo.o -L ${WAFER_DIR}/3rdparty/llvm/build/lib -lmlir_cuda_runtime -Wl,-rpath=${WAFER_DIR}/3rdparty/llvm/build/lib -march=native -o gpu.out

gpu.o: share.ll
	@${CLANG} -cc1 -triple nvptx64-nvidia-cuda -aux-triple x86_64-unknown-linux-gnu \
    	-target-cpu sm_75 -aux-target-cpu x86-64 -S -o gpu.s share.ll
	@${PTXAS} gpu.s -m64 -v --gpu-name sm_75 --output-file gpu.cubin -c
	@${FATBINARY} -64 --create gpu.fatbin --image=profile=sm_75,file=gpu.cubin \
                       --image=profile=compute_75,file=gpu.s -c
	@${CLANG} -cc1 -triple x86_64-unknown-linux-gnu -aux-triple nvptx64-nvidia-cuda -target-cpu x86-64 \
        -fcuda-include-gpubinary gpu.fatbin -emit-obj -o gpu.o share.ll

.PHONY: clean
clean:
	rm -rf *.out *.ll *.mlir *.s *cubin *fatbin *.o *.txt
